home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Caml Light 0.61 / Source / src / runtime / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-24  |  4.5 KB  |  206 lines  |  [TEXT/MPS ]

  1. /* Start-up code */
  2.  
  3. #include <stdio.h>
  4. #include <fcntl.h>
  5. #include "alloc.h"
  6. #include "exec.h"
  7. #include "fail.h"
  8. #include "gc.h"
  9. #include "globals.h"
  10. #include "intext.h"
  11. #include "io.h"
  12. #include "misc.h"
  13. #include "mlvalues.h"
  14. #include "stacks.h"
  15. #include "sys.h"
  16.  
  17. extern value interprete();
  18.  
  19. #ifndef O_BINARY
  20. #define O_BINARY 0
  21. #endif
  22.  
  23. header_t first_atoms[256];
  24. code_t start_code;
  25.  
  26. static void init_atoms()
  27. {
  28.   int i;
  29.   for(i = 0; i < 256; i++) first_atoms[i] = Make_header(0, i, White);
  30. }
  31.  
  32. static unsigned long read_size(p)
  33.      unsigned char * p;
  34. {
  35.   return ((unsigned long) p[0] << 24) + ((unsigned long) p[1] << 16) +
  36.          ((unsigned long) p[2] << 8) + p[3];
  37. }
  38.  
  39. #define FILE_NOT_FOUND (-1)
  40. #define TRUNCATED_FILE (-2)
  41. #define BAD_MAGIC_NUM (-3)
  42.  
  43. static int read_trailer(fd, trail)
  44.      int fd;
  45.      struct exec_trailer * trail;
  46. {
  47.   char buffer[TRAILER_SIZE];
  48.  
  49.   lseek(fd, (long) -TRAILER_SIZE, 2);
  50.   if (read(fd, buffer, TRAILER_SIZE) < TRAILER_SIZE) return TRUNCATED_FILE;
  51.   trail->code_size = read_size(buffer);
  52.   trail->data_size = read_size(buffer+4);
  53.   trail->symbol_size = read_size(buffer+8);
  54.   trail->debug_size = read_size(buffer+12);
  55.   trail->magic = read_size(buffer+16);
  56.   if (trail->magic == EXEC_MAGIC) return 0; else return BAD_MAGIC_NUM;
  57. }
  58.  
  59. extern char * searchpath();
  60.  
  61. int attempt_open(name, trail)
  62.      char ** name;
  63.      struct exec_trailer * trail;
  64. {
  65.   char * truename;
  66.   int fd;
  67.   int err;
  68.  
  69.   truename = searchpath(*name);
  70.   if (truename == 0) truename = *name; else *name = truename;
  71.   fd = open(truename, O_RDONLY | O_BINARY);
  72.   if (fd == -1) return FILE_NOT_FOUND;
  73.   err = read_trailer(fd, trail);
  74.   if (err != 0) { close(fd); return err; }
  75.   return fd;
  76. }
  77.  
  78. char usage[] =
  79. #ifdef SMALL
  80.   "usage: camlrun [-v] [-V] [-g generation size]\n               [-f free mem % min] [-F free mem % max] <file> <args>\n";
  81. #else
  82.   "usage: camlrun [-v] [-V] [-g generation size] [-F free mem %] <file> <args>\n";
  83. #endif
  84.  
  85. int main(argc, argv)
  86.      int argc;
  87.      char * argv[];
  88. {
  89.   int fd;
  90.   struct exec_trailer trail;
  91.   int i;
  92.   asize_t heap_size, generation_size;
  93.   struct longjmp_buffer raise_buf;
  94.   struct channel * chan;
  95.  
  96. #ifdef MSDOS
  97.   extern char ** check_args();
  98.   argv = check_args(argv);
  99. #endif
  100.  
  101.   heap_size = Heap_size;
  102.   generation_size = Generation_size;
  103.   free_mem_percent_min = Free_mem_percent_min;
  104.   free_mem_percent_max = Free_mem_percent_max;
  105.   verb_gc = 0;
  106. #ifdef DEBUG
  107.   verb_gc = 1;
  108. #endif
  109.  
  110.   i = 0;
  111.   fd = attempt_open(&argv[0], &trail);
  112.  
  113.   if (fd < 0) {
  114.  
  115.     for(i = 1; i < argc && argv[i][0] == '-'; i++) {
  116.       switch(argv[i][1]) {
  117.       case 'v':
  118.         verb_gc = 1;
  119.         break;
  120. #ifdef DEBUG
  121.       case 't':
  122.         { extern int trace_flag;
  123.           trace_flag = 1; }
  124.         break;
  125. #endif
  126.       case 'V':
  127.         { extern char version_string [];
  128.           fprintf(stderr, "%s", version_string);
  129.           exit(0);
  130.         }
  131.       case 'g':
  132.         generation_size = atoi(argv[++i]) * 256;
  133.         break;
  134. #ifdef SMALL
  135.       case 'f':
  136.         free_mem_percent_min = atoi(argv[++i]);
  137.         break;
  138. #endif
  139.       case 'F':
  140.         free_mem_percent_max = atoi(argv[++i]);
  141.         break;
  142.       default:
  143.         fatal_error("unknown option");
  144.       }
  145.     }
  146.  
  147.     if (argv[i] == 0) {
  148.       fprintf(stderr, "%s", usage);
  149.       exit(2);
  150.     }
  151.  
  152.     fd = attempt_open(&argv[i], &trail);
  153.  
  154.     switch(fd) {
  155.     case FILE_NOT_FOUND:
  156.       fprintf(stderr, "Fatal error: cannot find file %s\n", argv[i]);
  157.       exit(2);
  158.     case TRUNCATED_FILE:
  159.     case BAD_MAGIC_NUM:
  160.       fprintf(stderr,
  161.               "Fatal error: the file %s is not a bytecode executable file\n",
  162.               argv[i]);
  163.       exit(2);
  164.     }
  165.   }
  166.  
  167.   if (setjmp(raise_buf.buf) == 0) {
  168.  
  169.     external_raise = &raise_buf;
  170.  
  171.     init_memory(generation_size, heap_size);
  172.     init_stacks();
  173.     init_atoms();
  174.  
  175.     lseek(fd, - (long) (TRAILER_SIZE + trail.code_size + trail.data_size
  176.                         + trail.symbol_size + trail.debug_size), 2);
  177.  
  178.     start_code = (code_t) stat_alloc((asize_t) trail.code_size);
  179.     if ((unsigned) read(fd, start_code, (unsigned) trail.code_size)
  180.         != trail.code_size)
  181.       fatal_error("truncated bytecode file");
  182.  
  183. #if defined(BIG_ENDIAN) && !defined(ALIGNMENT)
  184.     fixup_endianness(start_code, (asize_t) trail.code_size);
  185. #endif
  186.  
  187.     chan = open_descriptor(Val_long(fd));
  188.     global_data = intern_val(chan);
  189.     modify(&Field(global_data, GLOBAL_DATA), global_data);
  190.     close_in(chan);
  191.  
  192.     sys_init(argv + i);
  193.     interprete(start_code);
  194.     sys_exit(0);
  195.  
  196.   } else {
  197.  
  198.     if (exn_bucket == Atom(OUT_OF_MEMORY_EXN))
  199.       fatal_error ("out of memory");
  200.     else
  201.       fatal_error ("uncaught exception");
  202.  
  203.   }
  204. }
  205.  
  206.